package prh25.biblioteca.service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import prh25.biblioteca.entity.Documento;
import prh25.biblioteca.entity.Usuario;
import prh25.biblioteca.entity.dao.DocumentoDAO;
import prh25.biblioteca.entity.dao.UsuarioDAO;
import prh25.biblioteca.entity.dao.hibernate.HibernateDAOFactory;
import prh25.biblioteca.entity.dao.hibernate.HibernateUtil;
import prh25.biblioteca.service.exception.LoginException;
import prh25.biblioteca.service.exception.UsuarioServiceException;


import java.io.*;
public class UsuarioServiceImpl implements UsuarioService{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	UsuarioDAO usuarioDAO;
	

	public UsuarioDAO getUsarioDAO() {
		/*
		File arquivo = new File(".");
		arquivo.getAbsolutePath()
		arquivo.getCanonicalPath()
		*/
		
		return usuarioDAO;
	}


	public void setUsarioDAO(UsuarioDAO usarioDAO) {
		this.usuarioDAO = usarioDAO;
	}


	@Override
	/**
	 * Responsavel por realizar o login de um usuario no sistema.
	 * @param usuario - O login do usuario no sistema.
	 * @param senha - A senha do usuario no sistema.
	 * @return O usuario identificado com o login e a senha passados.
	 */
	public Usuario login(String usuario, String senha) {
		// TODO Auto-generated method stub
		usuarioDAO = HibernateDAOFactory.DEFAULT.buildUsuarioDAO();
		List<Usuario> usuarioBd = usuarioDAO.findByLogin(usuario);
		//System.out.println(usuarioBd.isEmpty());
		
		if(usuarioBd.isEmpty() || (!usuarioBd.get(0).getSenha().equalsIgnoreCase(senha))){
			throw new LoginException("Usuario ou Senha Invalidos");
		}
		
		if(!usuarioBd.get(0).getAtivo()){
			throw new LoginException("Sua conta esta bloqueada. \n" +
					                "Ela pode ainda nao ter sido aprovada pelo administrador");
		}
		
		return usuarioBd.get(0);
		
		
		
		
	}


	@Override
	/**
	 * Lista todos os usuarios a partir de uma pesquisa realizada no
	 * banco de dados.
	 */
	public List<Usuario> listarUsuarios(String pesquisa) {
		// TODO Auto-generated method stub
		usuarioDAO = HibernateDAOFactory.DEFAULT.buildUsuarioDAO();
		List<Usuario> usuariosBd = new LinkedList<Usuario>();
		
		if(pesquisa.equalsIgnoreCase("ativos")){
			usuariosBd = usuarioDAO.findByAtivo(true);
		}else if(pesquisa.equalsIgnoreCase("bloqueados")){
			usuariosBd = usuarioDAO.findByAtivo(false);
		}else{
			usuariosBd = usuarioDAO.findAll();
		}
		
		return usuariosBd;
	}


	@Override
	/**
	 * Altera o status do usuario, ou seja, se o usuario foi desbloqueado
	 * ou nao pelo coordenador.
	 * @param login - O login que o usuario se cadastrou.
	 * @param situacao - O status atual no qual o usuario se encontra.
	 * @return O usuario que se deseja altera o seu status.
	 */
	public Usuario setSituacaoUsuario(String login, boolean situacao) {
		// TODO Auto-generated method stub
		usuarioDAO = HibernateDAOFactory.DEFAULT.buildUsuarioDAO();
		List<Usuario> usuarioBd = usuarioDAO.findByLogin(login);
		
		
		
		if(usuarioBd.isEmpty()){
			throw new UsuarioServiceException("Usuario nao Existe");
		}
		
		if((usuarioBd.get(0).getAtivo()) == situacao){
			throw new UsuarioServiceException("Situacao ja esta setada com esse valor");
		}
		
		Usuario usuario = usuarioBd.get(0);
		usuario.setAtivo(situacao);
		
		try {
			HibernateUtil.beginTransaction();
			usuarioDAO.saveOrUpdate(usuario);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {	
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
			throw new UsuarioServiceException("Nao foi possivel setar a situacao");
		}finally{
			HibernateUtil.getSession().flush();
			HibernateUtil.getSession().clear();
		}
		
		return usuario;
	}


	@Override
	/**
	 * Deleta um usuario do banco de dados.
	 * @param login - O login do usuario que sera excluido.
	 */
	public boolean excluirUsuario(String login) {
		// TODO Auto-generated method stub
		usuarioDAO = HibernateDAOFactory.DEFAULT.buildUsuarioDAO();
        List<Usuario> usuarioBd = usuarioDAO.findByLogin(login);
        
        
		
		
		if(usuarioBd.isEmpty()){
			throw new UsuarioServiceException("Usuario nao Existe");
		}
		
		Usuario usuario = usuarioBd.get(0);
		Set<Documento> documentosUsuario = usuario.getDocumentos();
		
		DocumentoDAO documentoDAO = HibernateDAOFactory.DEFAULT.buildDocumentoDAO();
		
		try {
			HibernateUtil.beginTransaction();
				
			
				Iterator<Documento> docsIterator = documentosUsuario.iterator();
				while(docsIterator.hasNext()){
					Documento doc = docsIterator.next();
					doc.setUsuario(null);
					documentoDAO.saveOrUpdate(doc);
				}
			
				usuario.setDocumentos(new HashSet<Documento>());
				usuarioDAO.delete(usuario);
			HibernateUtil.commitTransaction();
			
		} catch (Exception ex) {	
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
			
			throw new UsuarioServiceException("Nao foi possivel remover o usuario");
		}finally{
			HibernateUtil.getSession().flush();
			HibernateUtil.getSession().clear();
		}
		
		return true;
	}

}
